unit SimCell_Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, StdCtrls, AboutForm, BitGrid, ExtCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Exit1: TMenuItem;
    Help1: TMenuItem;
    Aboutthisprogram1: TMenuItem;
    InputWest: TCheckBox;
    InputNorth: TCheckBox;
    InputEast: TCheckBox;
    InputSouth: TCheckBox;
    LabelInputIndex: TLabel;
    CheckBoxNorth0: TCheckBox;
    CheckBoxNorth1: TCheckBox;
    CheckBoxNorth2: TCheckBox;
    CheckBoxNorth3: TCheckBox;
    CheckBoxNorth4: TCheckBox;
    CheckBoxNorth5: TCheckBox;
    CheckBoxNorth6: TCheckBox;
    CheckBoxNorth7: TCheckBox;
    CheckBoxNorth8: TCheckBox;
    CheckBoxNorth9: TCheckBox;
    CheckBoxNorth10: TCheckBox;
    CheckBoxNorth11: TCheckBox;
    CheckBoxNorth12: TCheckBox;
    CheckBoxNorth13: TCheckBox;
    CheckBoxNorth14: TCheckBox;
    CheckBoxNorth15: TCheckBox;
    LabelOutputNorth: TLabel;
    SaveAs1: TMenuItem;
    SaveDialog1: TSaveDialog;
    OpenDialog1: TOpenDialog;
    Open1: TMenuItem;
    N1: TMenuItem;
    CheckBoxWest0: TCheckBox;
    CheckBoxWest1: TCheckBox;
    CheckBoxWest2: TCheckBox;
    CheckBoxWest3: TCheckBox;
    CheckBoxWest4: TCheckBox;
    CheckBoxWest5: TCheckBox;
    CheckBoxWest6: TCheckBox;
    CheckBoxWest7: TCheckBox;
    CheckBoxWest8: TCheckBox;
    CheckBoxWest9: TCheckBox;
    CheckBoxWest10: TCheckBox;
    CheckBoxWest11: TCheckBox;
    CheckBoxWest12: TCheckBox;
    CheckBoxWest13: TCheckBox;
    CheckBoxWest14: TCheckBox;
    CheckBoxWest15: TCheckBox;
    LabelOutputWest: TLabel;
    CheckBoxSouth0: TCheckBox;
    CheckBoxSouth1: TCheckBox;
    CheckBoxSouth2: TCheckBox;
    CheckBoxSouth3: TCheckBox;
    CheckBoxSouth4: TCheckBox;
    CheckBoxSouth5: TCheckBox;
    CheckBoxSouth6: TCheckBox;
    CheckBoxSouth7: TCheckBox;
    CheckBoxSouth8: TCheckBox;
    CheckBoxSouth9: TCheckBox;
    CheckBoxSouth10: TCheckBox;
    CheckBoxSouth11: TCheckBox;
    CheckBoxSouth12: TCheckBox;
    CheckBoxSouth13: TCheckBox;
    CheckBoxSouth14: TCheckBox;
    CheckBoxSouth15: TCheckBox;
    LabelOutputSouth: TLabel;
    CheckBoxEast0: TCheckBox;
    CheckBoxEast1: TCheckBox;
    CheckBoxEast2: TCheckBox;
    CheckBoxEast3: TCheckBox;
    CheckBoxEast4: TCheckBox;
    CheckBoxEast5: TCheckBox;
    CheckBoxEast6: TCheckBox;
    CheckBoxEast7: TCheckBox;
    CheckBoxEast8: TCheckBox;
    CheckBoxEast9: TCheckBox;
    CheckBoxEast10: TCheckBox;
    CheckBoxEast11: TCheckBox;
    CheckBoxEast12: TCheckBox;
    CheckBoxEast13: TCheckBox;
    CheckBoxEast14: TCheckBox;
    CheckBoxEast15: TCheckBox;
    LabelOutputEast: TLabel;
    EditHex: TEdit;
    Label1: TLabel;
    Label_In: TLabel;
    Timer1: TTimer;
    procedure Exit1Click(Sender: TObject);
    procedure Aboutthisprogram1Click(Sender: TObject);
    procedure UpdateProgram(Sender: TObject);
    procedure UpdateInput(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SaveAs1Click(Sender: TObject);
    procedure Open1Click(Sender: TObject);
    procedure EditHexChange(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  ToBinary : Array[Boolean] of String = ('0','1');
var
  Cell       : tBitCell;
  Form1: TForm1;
  NorthCheck,
  WestCheck,
  SouthCheck,
  EastCheck  : Array[0..15] of TCheckBox;
  FileName   : String;
  FileSaved  : Boolean;
  busy       : boolean = false;  // prevents Checkbox and EditHex from fighting

implementation

{$R *.DFM}

procedure TForm1.Exit1Click(Sender: TObject);
begin
  Application.Terminate;
end;

procedure TForm1.Aboutthisprogram1Click(Sender: TObject);
begin
  FormAbout.Show;
end;

procedure TForm1.UpdateProgram(Sender: TObject);
var
  i : integer;
begin
  if busy then exit;
  busy := true;
  for i := 0 to 15 do
  begin
    cell.AsBit[i,North] := NorthCheck[i].checked;
    cell.AsBit[i,West ] := WestCheck[i].checked;
    cell.AsBit[i,South] := SouthCheck[i].checked;
    cell.AsBit[i,East ] := EastCheck[i].checked;
  end;
  EditHex.Text := Cell.AsHex;
  UpdateInput(Sender);

  LabelOutputNorth.Caption := 'Output: ' + ToBinary[Cell.Output[North]];
  LabelOutputWest.Caption  := 'Output: ' + ToBinary[Cell.Output[West ]];
  LabelOutputSouth.Caption := 'Output: ' + ToBinary[Cell.Output[South]];
  LabelOutputEast.Caption  := 'Output: ' + ToBinary[Cell.Output[East ]];
  FileSaved := False;
  busy := false;
end;

procedure TForm1.UpdateInput(Sender: TObject);
var
  newstr : string;
  OldIndex : Integer;
begin
  OldIndex := Cell.Index;                        // save old index in case it changes
  Cell.input[North] := InputNorth.Checked;       // update inputs to the cell
  Cell.input[South] := InputSouth.Checked;
  Cell.input[East]  := InputEast.Checked;
  Cell.input[West]  := InputWest.Checked;

  if Cell.Index <> OldIndex then  // we only need to update if the inputs change
  begin
    str(Cell.Index,newstr);
    LabelInputIndex.Caption := 'Input Index: ' + NewStr;
    NorthCheck[OldIndex].Color := clBtnFace;
    NorthCheck[Cell.Index].Color := clRed;
    WestCheck[ OldIndex].Color := clBtnFace;
    WestCheck[ Cell.Index].Color := clRed;
    SouthCheck[Oldindex].Color := clBtnFace;
    SouthCheck[Cell.Index].Color := clRed;
    EastCheck[ OldIndex].Color := clBtnFace;
    EastCheck[ Cell.Index].Color := clRed;
    LabelOutputNorth.Caption := 'Output: ' + ToBinary[Cell.Output[North]];
    LabelOutputWest.Caption  := 'Output: ' + ToBinary[Cell.Output[West ]];
    LabelOutputSouth.Caption := 'Output: ' + ToBinary[Cell.Output[South]];
    LabelOutputEast.Caption  := 'Output: ' + ToBinary[Cell.Output[East ]];
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Cell := tBitCell.Init;        // set up the emulation cell
  FileName   := 'untitled.bg';
  FileSaved  := false;
  NorthCheck[0]  := CheckBoxNorth0;
  NorthCheck[1]  := CheckBoxNorth1;
  NorthCheck[2]  := CheckBoxNorth2;
  NorthCheck[3]  := CheckBoxNorth3;
  NorthCheck[4]  := CheckBoxNorth4;
  NorthCheck[5]  := CheckBoxNorth5;
  NorthCheck[6]  := CheckBoxNorth6;
  NorthCheck[7]  := CheckBoxNorth7;
  NorthCheck[8]  := CheckBoxNorth8;
  NorthCheck[9]  := CheckBoxNorth9;
  NorthCheck[10]  := CheckBoxNorth10;
  NorthCheck[11]  := CheckBoxNorth11;
  NorthCheck[12]  := CheckBoxNorth12;
  NorthCheck[13]  := CheckBoxNorth13;
  NorthCheck[14]  := CheckBoxNorth14;
  NorthCheck[15]  := CheckBoxNorth15;
  WestCheck[0]  := CheckBoxWest0;
  WestCheck[1]  := CheckBoxWest1;
  WestCheck[2]  := CheckBoxWest2;
  WestCheck[3]  := CheckBoxWest3;
  WestCheck[4]  := CheckBoxWest4;
  WestCheck[5]  := CheckBoxWest5;
  WestCheck[6]  := CheckBoxWest6;
  WestCheck[7]  := CheckBoxWest7;
  WestCheck[8]  := CheckBoxWest8;
  WestCheck[9]  := CheckBoxWest9;
  WestCheck[10]  := CheckBoxWest10;
  WestCheck[11]  := CheckBoxWest11;
  WestCheck[12]  := CheckBoxWest12;
  WestCheck[13]  := CheckBoxWest13;
  WestCheck[14]  := CheckBoxWest14;
  WestCheck[15]  := CheckBoxWest15;
  SouthCheck[0]  := CheckBoxSouth0;
  SouthCheck[1]  := CheckBoxSouth1;
  SouthCheck[2]  := CheckBoxSouth2;
  SouthCheck[3]  := CheckBoxSouth3;
  SouthCheck[4]  := CheckBoxSouth4;
  SouthCheck[5]  := CheckBoxSouth5;
  SouthCheck[6]  := CheckBoxSouth6;
  SouthCheck[7]  := CheckBoxSouth7;
  SouthCheck[8]  := CheckBoxSouth8;
  SouthCheck[9]  := CheckBoxSouth9;
  SouthCheck[10]  := CheckBoxSouth10;
  SouthCheck[11]  := CheckBoxSouth11;
  SouthCheck[12]  := CheckBoxSouth12;
  SouthCheck[13]  := CheckBoxSouth13;
  SouthCheck[14]  := CheckBoxSouth14;
  SouthCheck[15]  := CheckBoxSouth15;
  EastCheck[0]  := CheckBoxEast0;
  EastCheck[1]  := CheckBoxEast1;
  EastCheck[2]  := CheckBoxEast2;
  EastCheck[3]  := CheckBoxEast3;
  EastCheck[4]  := CheckBoxEast4;
  EastCheck[5]  := CheckBoxEast5;
  EastCheck[6]  := CheckBoxEast6;
  EastCheck[7]  := CheckBoxEast7;
  EastCheck[8]  := CheckBoxEast8;
  EastCheck[9]  := CheckBoxEast9;
  EastCheck[10]  := CheckBoxEast10;
  EastCheck[11]  := CheckBoxEast11;
  EastCheck[12]  := CheckBoxEast12;
  EastCheck[13]  := CheckBoxEast13;
  EastCheck[14]  := CheckBoxEast14;
  EastCheck[15]  := CheckBoxEast15;
end;

procedure TForm1.SaveAs1Click(Sender: TObject);
var
  f : textfile;
  i : integer;
begin
  If SaveDialog1.Execute then
  begin
    filename := SaveDialog1.filename;
    Form1.Caption := 'BitGrid Simulator - '+Filename;
    AssignFile(f,filename);
    Rewrite(f);
    For i := 0 to 15 do
      writeln(f,ToBinary[NorthCheck[i].Checked],
                ToBinary[WestCheck[i].Checked],
                ToBinary[SouthCheck[i].Checked],
                ToBinary[EastCheck[i].Checked]);
    closefile(f);
    FileSaved := True;
  end;
end;

procedure TForm1.Open1Click(Sender: TObject);
var
  f : textfile;
  i : integer;
  s : string;
begin
  If OpenDialog1.Execute then
  begin
    FileName := OpenDialog1.FileName;
    Form1.Caption := 'BitGrid Simulator - '+Filename;
    AssignFile(f,filename);
    Reset(f);
    for i := 0 to 15 do
    begin
      readln(f,s);  s := s + '    '; // make sure there are at least 4 chars!
      NorthCheck[i].checked := (s[1] = '1');
      WestCheck[i].checked  := (s[2] = '1');
      SouthCheck[i].checked := (s[3] = '1');
      EastCheck[i].checked  := (s[4] = '1');
    end;
    closefile(f);
    FileSaved := True; { we just opened it, we don't need to save it }
  end;
end;


procedure TForm1.EditHexChange(Sender: TObject);
var
  i : byte;
  s : string;
begin
  if busy then exit;
  busy := true;
  S := TEdit(Sender).Text;
  Cell.AsHex := S;

  for i := 0 to 15 do
  begin
    NorthCheck[i].checked := cell.AsBit[i,North];
    WestCheck[ i].checked := cell.AsBit[i,West];
    SouthCheck[i].checked := cell.AsBit[i,South];
    EastCheck[ i].checked := cell.AsBit[i,East];
  end;
  busy := false;
  updateprogram(sender);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label_in.Caption := Format('Input Transitions: %d',[BitGrid.InputCount]);
end;

end.
